package com.zxjbyte.yiyi.framework.common.core.excel.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.google.common.collect.Lists;
import com.zxjbyte.yiyi.framework.common.core.excel.processor.IReadExcelProcessor;
import lombok.RequiredArgsConstructor;

import java.util.List;
import java.util.Map;

/**
 * Excel监听器
 *
 * @Author zhangxingjia
 * @Date 2023/3/21 21:24
 * @Version: 1.0
 */
@RequiredArgsConstructor // 每次创建Listener的时候需要把spring管理的类传进来
public class ReadExcelListener<T> extends AnalysisEventListener<T> {

    /**
     * 每隔500条数据处理，然后清理list ，方便内存回收
     */
    private static final int BATCH_COUNT = 500;

    /**
     * 缓存的数据
     */
    private final List<T> cachedDataList = Lists.newArrayListWithExpectedSize(BATCH_COUNT);

    /**
     * 读取的数据处理
     */
    private final IReadExcelProcessor<T> readExcelProcessor;

    @Override
    public void invoke(T t, AnalysisContext analysisContext) {
        cachedDataList.add(t);
        // 达到BATCH_COUNT，则调用processor方法处理，防止数据几万条数据在内存，容易OOM
        if (cachedDataList.size() >= BATCH_COUNT) {
            processor();
            // 存储完成清理list
            cachedDataList.clear();
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        // 这里也要处理数据，确保最后遗留的数据也处理掉
        processor();
        cachedDataList.clear();
    }

    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        readExcelProcessor.processorHandMap(headMap);
    }

    private void processor(){
        // 调用processor方法处理
        readExcelProcessor.processorDataList(cachedDataList);
    }
}
